package Network;

import java.util.LinkedList;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import Utility.LogContext;
import Utility.LogManager;


import Context.Constant;
import Context.ContextHolder;
import Data.SendingMessage;

public class ReceiveMessageQueue {

    private Semaphore emptySemaphore;

    private Semaphore fullSemaphore;
    
    private LinkedList<SendingMessage> msgReceivingQueue;
    
    private Lock msgReceivingLock;
    
    public ReceiveMessageQueue() {
    	LogManager.getSingletonManager().writeLog(
    			"Begin initializing the receiving message queue", LogContext.LOG_INFO);
    	try {
    		int maxReceivingLength = Integer.parseInt(
    				ContextHolder.getContext().getProperty(Constant.MAX_MSGRECEIVING_QUEUE));
    		
    		emptySemaphore = new Semaphore(maxReceivingLength);
    		fullSemaphore = new Semaphore(0);
    		msgReceivingQueue = new LinkedList<SendingMessage>();
    		msgReceivingLock = new ReentrantLock();
    	}
    	catch (NumberFormatException e) {
			// TODO: handle exception
    		e.printStackTrace();
		}
    	LogManager.getSingletonManager().writeLog(
    			"End initializing the receiving message queue", LogContext.LOG_INFO);
    }
    
    public void pushReceivedMessage(SendingMessage message){
    	try {
	    	emptySemaphore.acquire();
	    	msgReceivingLock.lock();
	    	msgReceivingQueue.add(message);
	    	msgReceivingLock.unlock();
	    	fullSemaphore.release();
	    } catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
    }
    public SendingMessage pollReceivedMessage(){
    	SendingMessage message = null;
    	try {
	    	fullSemaphore.acquire();
	    	msgReceivingLock.lock();
	        message = msgReceivingQueue.removeFirst();
	        msgReceivingLock.unlock();
	        emptySemaphore.release();
	    } catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return message;
    }
}
